----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    20:32:22 11/30/2014 
-- Design Name: 
-- Module Name:    alu - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

-- 0000 nop
-- 0001 +
-- 0010 -
-- 0011 &
-- 0100 |
-- 0101 !=
-- 0110 <
-- 0111 sll
-- 1000 sra
-- 1001 sllv
-- 1010 srav
-- 1011 not
entity alu is
	port(alucode:in std_logic_vector(3 downto 0);
		a,b:in std_logic_vector(15 downto 0);
		sign,zero,over,co:out std_logic;
		y:out std_logic_vector(15 downto 0)
		);
end alu;

architecture Behavioral of alu is

begin
	process(alucode,a,b)
	begin
		case alucode is
		when "0000"=>--nop
			y(15 downto 0)<=b(15 downto 0);
			over<='0';
			co<='0';
			sign<=a(15);
			if(a="0000000000000000") then
				zero<='1';
			else zero<='0';
			end if;
		when "0001"=>--+
			y(15 downto 0)<=a(15 downto 0)+b(15 downto 0);
			if a(15 downto 0)+b(15 downto 0)<a(15 downto 0) then
				co<='1';
				over<='1';
			else
				co<='0';
				over<='0';
			end if;
			if a(15 downto 0)+b(15 downto 0)="0000000000000000" then
				zero<='1';
			else zero<='0';
			end if;
		when "0010"=>---
			y(15 downto 0)<=a(15 downto 0)-b(15 downto 0);
			if a(15 downto 0)-b(15 downto 0)>a(15 downto 0) then
				over<='1';
				co<='1';
			else
				over<='0';
				co<='0';
			end if;
			if(a-b="0000000000000000") then
				zero<='1';
			else zero<='0';
			end if;
		when "0011"=>--&
			y(15 downto 0)<=a(15 downto 0) and b(15 downto 0);
			over<='0';
			co<='0';
			if (a and b) ="0000000000000000" then
				zero<='1';
			else zero<='0';
			end if;
		when "0100"=>--|
			y(15 downto 0)<=a(15 downto 0) or b(15 downto 0);
			over<='0';
			co<='0';
			if (a or b)="0000000000000000" then
				zero<='1';
			else zero<='0';
			end if;
		when "0101"=>--!=
			if a(15 downto 0)=b(15 downto 0) then
				y(15 downto 0)<="0000000000000000";
				zero<='1';
			else
				y(15 downto 0)<="0000000000000001";
				zero<='0';
			end if;
			co<='0';
			over<='0';
		when "0110"=>--<
			if a(15 downto 0)<b(15 downto 0) then
				y(15 downto 0)<="0000000000000001";
				zero<='0';
			else
				y(15 downto 0)<="0000000000000000";
				zero<='1';
			end if;
			co<='0';
			over<='0';
		when "0111"=>--sll
			if b(15 downto 0)="0000000000000000" then
				y(15 downto 0)<=to_stdlogicvector(to_bitvector(a(15 downto 0)) sll 8);
				if to_stdlogicvector(to_bitvector(a(15 downto 0)) sll 8)="0000000000000000" then
					zero<='1';
				else zero<='0';
				end if;
			else
				y(15 downto 0)<=to_stdlogicvector(to_bitvector(a(15 downto 0)) sll to_integer(unsigned(b(15 downto 0))));
				if to_stdlogicvector(to_bitvector(a(15 downto 0)) sll to_integer(unsigned(b(15 downto 0))))="0000000000000000" then
					zero<='1';
				else zero<='0';
				end if;
			end if;
			co<='0';
			over<='0';
		when "1000"=>--sra
			if b(15 downto 0)="0000000000000000" then
				y(15 downto 0)<=to_stdlogicvector(to_bitvector(a(15 downto 0)) sra 8);
				if to_stdlogicvector(to_bitvector(a(15 downto 0)) sra 8)="0000000000000000" then
					zero<='1';
				else zero<='0';
				end if;
			else
				y(15 downto 0)<=to_stdlogicvector(to_bitvector(a(15 downto 0)) sra to_integer(unsigned(b(15 downto 0))));
				if to_stdlogicvector(to_bitvector(a(15 downto 0)) sra to_integer(unsigned(b(15 downto 0)))) 
					="0000000000000000" then
					zero<='1';
				else zero<='0';
				end if;
			end if;
			co<='0';
			over<='0';
		when "1001"=>--sllv
			y(15 downto 0)<=to_stdlogicvector(to_bitvector(a(15 downto 0)) sll to_integer(unsigned(b(15 downto 0))));
			if to_stdlogicvector(to_bitvector(a(15 downto 0)) sll to_integer(unsigned(b(15 downto 0))))="0000000000000000" then
				zero<='1';
			else zero<='0';
			end if;
			co<='0';
			over<='0';
		when "1010"=>--srav
			y(15 downto 0)<=to_stdlogicvector(to_bitvector(a(15 downto 0)) sra to_integer(unsigned(b(15 downto 0))));
			if to_stdlogicvector(to_bitvector(a(15 downto 0)) sra to_integer(unsigned(b(15 downto 0)))) 
				="0000000000000000" then
				zero<='1';
			else zero<='0';
			end if;
			co<='0';
			over<='0';
		when "1011"=>--not
			y(15 downto 0)<=not a(15 downto 0);
			co<='0';
			over<='0';
			if a="0000000000000000" then
				zero<='0';
			else zero<='1';
			end if;
		when others=>
			y(15 downto 0)<="0000000000000000";
			zero<='1';
			over<='0';
			co<='0';
		end case;
	end process;

end Behavioral;

